/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
 
#include "interface.h"

/* Implementação das funções relaciondas à interface do servidor */

// trata a interrupção Crtl + C e a maneira como o servidor deve reagir ao sinal
void func_interruption(int signum)
{
	puts("\nSinal Recebido!\n");
        close_cache();
	exit(0);
}

// obtem as configurações do arquivo de configuração e atribui aos parâmetros do servidor
void configure_webserver(vstring *conf)
{
    vstring *data = NULL,*line = NULL;
    // leitura do arquivo de configuração, conteúdo é copiado para *data
    read_file(conf,&data);
    // enquanto o arquivo contiver linhas para serem analisadas...
    while(get_line(&line,&data))
    {        
        remove_comment(&line);
        trim(&line);
        // verifica se ainda tem informação para ser processada
        if(line != NULL)
        {
            if(remove_occour(&line,P_PORT))
            {
                trim(&line);
                copy_vstring(&(configure.port),line);
            }
            if(remove_occour(&line,P_THREADS))
            {
                trim(&line);
                string_to_integer(line,&(configure.threads));
            }
            if(remove_occour(&line,P_FILE_DEFAULT))
            {
                trim(&line);
                copy_vstring(&(configure.file_default),line);
            }
            if(remove_occour(&line,P_SERVER_DIRECTORY))
            {
                trim(&line);
                copy_vstring(&(configure.server_dir),line);
            }
            if(remove_occour(&line,P_CGI_BIN_DIRECTORY))
            {
                trim(&line);
                copy_vstring(&(configure.cgi_dir),line);
            }

            if(remove_occour(&line,P_CACHE_DIRECTORY))
            {
                trim(&line);
                copy_vstring(&(configure.cache_dir),line);
            }

            if(remove_occour(&line,P_CACHE_SIZE_L1))
            {
                trim(&line);
                string_to_integer(line,&(configure.cache_size_l1));
            }

            if(remove_occour(&line,P_CACHE_SIZE_L2))
            {
                trim(&line);
                string_to_integer(line,&(configure.cache_size_l2));
            }
            // TODO mais ifs para os próximos parametros
        }
    }
}

// manipula a linha de comando para chamar o servidor
void cmdl_handling(int argc, char* argv[])
{
    int poolthreads = 0,erro = 0;
    size_t i,j;
    char parametro;
    vstring *port = NULL;

    copy_vstring(&port,configure.port);

    parametro = '\0';

    if(argc >= 2 && argc <= 4)
        for(i = 1; i < (size_t)argc; i++)
            switch (argv[i][0])
            {
                case '-':
                    parametro = argv[i][1];
                    break;
                default:
                    if(argv[i - 1][0] == '-' && argv[i - 1][1] == 't')
                    {
                        poolthreads = 0;
                        for(j = 0; j < strlen(argv[i]) && !erro; j++)	// transformação da string contida em argv[i] em número
                            if((argv[i][j] - 48) <= 9 && (argv[i][j] - 48) >= 0 && !erro)
                                poolthreads = poolthreads * 10 + argv[i][j] - 48;
                            else
                                erro = 1;
                    }
                    else
                    {
                        for(j = 0; j < strlen(argv[i]) && !erro; j++)	// transformação da string contida em argv[i] em número
                            if(argv[i][j] > '9' || argv[i][j] < '0')
                                erro = 1;
                        if(!erro)
                            copy_string(&port,argv[i]);
                    }
            }
    else
        erro = 1;

    if((parametro == 't' && !poolthreads) || (parametro != 'f' && parametro != 't' && parametro != 'm'))
        erro = 1;

    if(erro)
    {
        printf("Uso: %s <parametro(-f/-t)> <tamanho poolthreads( /N)> <porta(default=%s)>\n\n",argv[0],configure.port->pt);
        return ;
    }

    switch(parametro)
    {
        case 'f':
            multi_httpd(port,0); // 0: funcionamento normal
            break;
        case 't':
            thread_httpd(port,poolthreads); // multi-thread
            break;
        case 'm':
            multi_httpd(port,1); // 1: manutenção
    }
}

void start(int argc, char* argv[])
{
    vstring *conf = NULL;
    copy_string(&conf,CONF_DEFAULT);
    configure_webserver(conf);
    print_config();
    new_cache();
    init_cache();

    cmdl_handling(argc, argv);
}